﻿--[[-------------------------------------------------

    SA-MP Kill Messages для MTA:SA (DX версия)
    от MX_Master'а

    * Это клиентский скрипт
    * Кодировка файла - UTF8
    * Протестировано на MTA:SA 1.0.4

--]]---------------

---
-- НАСТРОЙКИ (можно изменить под себя) --
---

-- текущее разрешение экрана игрока
local screen_maxX,      screen_maxY =           guiGetScreenSize()
-- относительная процентная позиция центра самой верхней иконки
local icon1_centerX,    icon1_topY =            0.84,                   0.3
-- реальная ширина, высота изображения иконки
local icon_width,       icon_height =           24,                     24
-- отображаемая ширина, высота изображения иконки
local icon_sideMargin,  icon_bottomMargin =     10,                     5
-- ширина, высота поля с текстом
local label_width,      label_height =          200,                    20
-- шрифт, смещение вниз верхней точки текста от верхней точки иконки
local label_font,       label_topMargin =       "default-bold",         3
-- цвет тени под текстом
local label_shadowColor = tocolor(12,12,12)
-- кол-во рядов в кил панельке
local rows = 5

-- таблица, где хранятся данные каждого ряда кил панельки
local killRow = {}

-- таблица, где хранятся пути к иконкам причин смертей под нужными индексами
local imagePath = {
    [0] =  "icons/weapons/fist.png",
    [1] =  "icons/weapons/brassKnuckles.png",
    [2] =  "icons/weapons/golfClub.png",
    [3] =  "icons/weapons/nightstick.png",
    [4] =  "icons/weapons/knife.png",
    [5] =  "icons/weapons/baseballBat.png",
    [6] =  "icons/weapons/shovel.png",
    [7] =  "icons/weapons/poolCue.png",
    [8] =  "icons/weapons/katana.png",
    [9] =  "icons/weapons/chainsaw.png",
    [10] = "icons/weapons/dildo.png",
    [11] = "icons/weapons/dildo.png",
    [12] = "icons/weapons/dildo.png",
    [13] = "icons/deathReasons/death.png", -- возможно, никогда не используется
    [14] = "icons/weapons/flowers.png",
    [15] = "icons/weapons/cane.png",
    [16] = "icons/weapons/grenade.png",
    [17] = "icons/weapons/tearGas.png",
    [18] = "icons/weapons/molotovCocktail.png",
    [19] = "icons/weapons/rocketLauncher.png", -- возможно, никогда не используется
    [20] = "icons/weapons/hsRocketLauncher.png", -- возможно, никогда не используется
    [21] = "icons/deathReasons/explosion.png", -- возможно, никогда не используется
    [22] = "icons/weapons/9mm.png",
    [23] = "icons/weapons/silenced9mm.png",
    [24] = "icons/weapons/desertEagle.png",
    [25] = "icons/weapons/shotgun.png",
    [26] = "icons/weapons/sawnoffShotgun.png",
    [27] = "icons/weapons/combatShotgun.png",
    [28] = "icons/weapons/microSmg.png",
    [29] = "icons/weapons/mp5.png",
    [30] = "icons/weapons/ak47.png",
    [31] = "icons/weapons/m4.png",
    [32] = "icons/weapons/tec9.png",
    [33] = "icons/weapons/countryRifle.png",
    [34] = "icons/weapons/sniperRifle.png",
    [35] = "icons/weapons/rocketLauncher.png",
    [36] = "icons/weapons/hsRocketLauncher.png",
    [37] = "icons/weapons/flamethrower.png",
    [38] = "icons/weapons/minigun.png",
    [39] = "icons/weapons/satchelCharge.png",
    [40] = "icons/weapons/detonator.png", -- возможно, никогда не используется
    [41] = "icons/weapons/spraycan.png",
    [42] = "icons/weapons/fireExtinguisher.png",
    [43] = "icons/deathReasons/explosion.png", -- возможно, никогда не используется
    [44] = "icons/weapons/goggles.png", -- возможно, никогда не используется
    [45] = "icons/weapons/goggles.png", -- возможно, никогда не используется
    [46] = "icons/weapons/parachute.png", -- возможно, никогда не используется

    [49] =  "icons/deathReasons/rammed.png",
    [50] =  "icons/deathReasons/helicopterBlades.png",
    [51] =  "icons/deathReasons/explosion.png",
    [52] =  "icons/deathReasons/fire.png",
    [53] =  "icons/deathReasons/death.png",
    [54] =  "icons/deathReasons/fall.png",
    [255] = "icons/deathReasons/death.png",

    ['connected'] =    "icons/connectStates/connected.png",
    ['disconnected'] = "icons/connectStates/disconnected.png"
}




---
-- ПОДСЧЕТЫ СОГЛАСНО НАСТРОЕК (нельзя изменять) --
---

local rows_margin =     icon_height + icon_bottomMargin

local label1_leftX =    screen_maxX * icon1_centerX - icon_width/2 - icon_sideMargin - label_width
local label1_rightX =   label1_leftX + label_width
local label2_leftX =    label1_rightX + icon_sideMargin*2 + icon_width
local label2_rightX =   label2_leftX + label_width

local icon_leftX =      label1_rightX + icon_sideMargin
local icon_topY =       screen_maxY * icon1_topY




---
-- ИНСТРУМЕНТЫ --
---

-- добавляет в кил панельку новый ряд в конец (внизу)
function showClientDeathMessage ( killerName, killerNameColor, deathReason, victimName, victimNameColor )

    -- сохраним первый ряд во временную переменную, т.к. он будет замещен
    local firstRow = killRow[1]



    -- перенесем текущие ряды на 1 вверх
    for r = 1, rows - 1 do
        killRow[r] = killRow[r + 1]
    end



    -- изменим данные последнего (нижнего) ряда

    -- предпроверки входных данных
    if type(killerNameColor) ~= "table" then killerNameColor = {255,255,255} end
    if type(victimNameColor) ~= "table" then victimNameColor = {255,255,255} end

    -- если первый ряд существует, скопируем его адрес в последний ряд
    -- и просто изменим его параметры на новые
    if firstRow then

        killRow[rows] = firstRow

        killRow[rows]["killerName"] =       tostring(killerName)
        killRow[rows]["killerNameColor"] =  tocolor( unpack(killerNameColor) )
        killRow[rows]["deathReason"] =      deathReason
        killRow[rows]["victimName"] =       tostring(victimName)
        killRow[rows]["victimNameColor"] =  tocolor( unpack(victimNameColor) )

    -- если первый ряд еще не существует, то копировать его адрес не будем,
    -- а создадим в последнем ряду новую таблицу с заданными параметрами
    else
        killRow[rows] = {
            ["killerNamePos"] =     { leftX = label1_leftX, rightX = label1_rightX, topY = 0, bottomY = 0 },
            ["reasonIconPos"] =     { leftX = icon_leftX, topY = 0 },
            ["victimNamePos"] =     { leftX = label2_leftX, rightX = label2_rightX, topY = 0, bottomY = 0 },

            ["killerName"] =        tostring(killerName),
            ["killerNameColor"] =   tocolor( unpack(killerNameColor) ),
            ["deathReason"] =       deathReason,
            ["victimName"] =        tostring(victimName),
            ["victimNameColor"] =   tocolor( unpack(victimNameColor) )
        }
    end

    -- постпроверки измененных данных

    -- если причина смерти неизвестна, заменим ее просто на "смерть"
    if imagePath[ killRow[rows]["deathReason"] ] == nil then
        killRow[rows]["deathReason"] = 255
    end

    -- если имя киллера = имя жертвы
    if killRow[rows]["killerName"] == killRow[rows]["victimName"] then
        killRow[rows]["killerName"] = ""
    end



    -- обновим позиции элементов панельки
    local y = icon_topY

    for r = 1, rows do
        -- если ряд существует
        if killRow[r] then
            -- обновим позицию левого текста от иконки
            killRow[r]["killerNamePos"]["topY"] =       y + label_topMargin
            killRow[r]["killerNamePos"]["bottomY"] =    y + label_height

            -- обновим позицию иконки
            killRow[r]["reasonIconPos"]["topY"] =       y

            -- обновим позицию правого текста от иконки
            killRow[r]["victimNamePos"]["topY"] =       killRow[r]["killerNamePos"]["topY"]
            killRow[r]["victimNamePos"]["bottomY"] =    killRow[r]["killerNamePos"]["bottomY"]
        end

        y = y + rows_margin
    end

end

-- сделаем свою функцию для получения цвета ника игрока
__getPlayerNametagColor = getPlayerNametagColor
function getPlayerNametagColor ( player )
    local team = getPlayerTeam(player)
    
    if team then
        return getTeamColor(team)
    end
    
    return __getPlayerNametagColor(player)
end




---
-- ОБРАБОТЧИКИ --
---

-- если умер какой-то онлайн игрок
addEventHandler( "onClientPlayerWasted", root,
    function ( killer, deathReason )
        -- если жертва это не игрок, то выводить на экран кил сообщение не надо
        if getElementType(source) ~= "player" then return end

        local killerName, killerNameColor = false, false

        -- если киллер это не игрок
        if not isElement(killer) then
            killerName =        ''
            killerNameColor =   {0,0,0}
        -- если киллер это транспорт
        elseif getElementType(killer) == "vehicle" then
            if deathReason == 50 and getVehicleType(killer) ~= 'Helicopter' then
                deathReason = 49
            end
            
            -- пробьем водилу
            local driver = getVehicleController(killer)

            if driver then
                killerName =        getPlayerName(driver)
                killerNameColor =   { getPlayerNametagColor(driver) }
            else
                killerName =        ''
                killerNameColor =   {0,0,0}
            end
        -- а если киллер это игрок, то
        else
            killerName =        getPlayerName(killer)
            killerNameColor =   { getPlayerNametagColor(killer) }
        end

        -- если использовалась одна из 2 видов ракет
        if (deathReason == 19) or (deathReason == 20) or (deathReason == 21) then
            if getElementType(killer) == "player" and not isPedInVehicle(killer) then
                deathReason = getPedWeapon(killer)
            end
        end

        -- добавим в кил панельку новый ряд
        showClientDeathMessage ( 
            killerName, killerNameColor,
            deathReason,
            getPlayerName(source), { getPlayerNametagColor(source) } 
        )
    end
)

-- если какой-то игрок вошел на сервер
addEventHandler( "onClientPlayerJoin", root,
    function()
        showClientDeathMessage (
            getPlayerName(source), {255,255,255},
            "connected",
            "", {0,0,0} 
        )
    end
)

-- если какой-то игрок вышел с сервера
addEventHandler( "onClientPlayerQuit", root,
    function()
        showClientDeathMessage (
            getPlayerName(source), {200,200,200},
            "disconnected",
            "", {0,0,0} 
        )
    end
)

-- рисует панельку на экране игрока в каждом кадре
function renderClientKillPanel ()
    -- пробежимся по всем рядам
    for r = 1, rows do
        -- если текущий ряд существует
        if killRow[r] then
            -- нарисуем на экране тень надписи с именем киллера
            dxDrawText( killRow[r]["killerName"],
                killRow[r]["killerNamePos"]["leftX"] + 1,  killRow[r]["killerNamePos"]["topY"] + 1,
                killRow[r]["killerNamePos"]["rightX"] + 1, killRow[r]["killerNamePos"]["bottomY"] + 1,
                label_shadowColor, -- цвет в формате 0xXXXXXXXX (integer)
                1, -- масштаб (float)
                label_font, -- шрифт (string)
                "right" ) -- гориз. выравнивание (string)

            -- нарисуем на экране надпись с именем киллера
            dxDrawText( killRow[r]["killerName"],
                killRow[r]["killerNamePos"]["leftX"],  killRow[r]["killerNamePos"]["topY"],
                killRow[r]["killerNamePos"]["rightX"], killRow[r]["killerNamePos"]["bottomY"],
                killRow[r]["killerNameColor"], -- цвет в формате 0xXXXXXXXX (integer)
                1, -- масштаб (float)
                label_font, -- шрифт (string)
                "right" ) -- гориз. выравнивание (string)

            -- нарисуем иконку
            dxDrawImageSection( killRow[r]["reasonIconPos"]["leftX"], killRow[r]["reasonIconPos"]["topY"],
                icon_width, icon_height,
                0, 0,
                icon_width, icon_height,
                imagePath[ killRow[r]["deathReason"] ] )

            -- нарисуем на экране тень надписи с именем жертвы
            dxDrawText( killRow[r]["victimName"],
                killRow[r]["victimNamePos"]["leftX"] + 1,  killRow[r]["victimNamePos"]["topY"] + 1,
                killRow[r]["victimNamePos"]["rightX"] + 1, killRow[r]["victimNamePos"]["bottomY"] + 1,
                label_shadowColor, -- цвет в формате 0xXXXXXXXX (integer)
                1, -- масштаб (float)
                label_font ) -- шрифт (string)

            -- нарисуем на экране надпись с именем жертвы
            dxDrawText( killRow[r]["victimName"],
                killRow[r]["victimNamePos"]["leftX"],  killRow[r]["victimNamePos"]["topY"],
                killRow[r]["victimNamePos"]["rightX"], killRow[r]["victimNamePos"]["bottomY"],
                killRow[r]["victimNameColor"], -- цвет в формате 0xXXXXXXXX (integer)
                1, -- масштаб (float)
                label_font ) -- шрифт (string)
        end
    end
end
addEventHandler ( "onClientRender", root, renderClientKillPanel )

-- выводит в килл панельку несколько тестовых рядов
-- эти ряды видны только игроку, который ввел команду,
-- указанную после блока этой функции
function killPanelTest()

    showClientDeathMessage( "oldPlayerName", { math.random(0,255), math.random(0,255), math.random(0,255) },
        "disconnected",
        "", {0,0,0} )

    for r = 2, rows - 1 do
        local c, nameLen, name1, name2 = 1, math.random(4,20), "", ""

        while c <= nameLen do
            name1 = name1 .. string.char( math.random(33,125) )
            c = c + 1
        end

        c, nameLen = 1, math.random(4,20)
        while c <= nameLen do
            name2 = name2 .. string.char( math.random(33,125) )
            c = c + 1
        end

        showClientDeathMessage( name1, { math.random(0,255), math.random(0,255), math.random(0,255) },
            math.random(0,54),
            name2, { math.random(0,255), math.random(0,255), math.random(0,255) } )
    end

    showClientDeathMessage( "newPlayerHere", { math.random(0,255), math.random(0,255), math.random(0,255) },
        "connected",
        "", {0,0,0} )

end
addCommandHandler( "killmsgtest", killPanelTest, false )
